package com.witmore.neutron.ai.web.apiv2.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jk.common.response.ResponseResult;
import com.jk.mp.wx.response.WechatAuthAccessToken;
import com.witmore.neutron.ai.db.entity.UserDO;
import com.witmore.neutron.ai.db.mapper.UserMapper;
import com.witmore.neutron.ai.web.apiv2.controller.vo.SendSmsCodeParam;
import com.witmore.neutron.ai.web.apiv2.controller.vo.UserBindOpenidParam;
import com.witmore.neutron.ai.web.apiv2.controller.vo.UserBindPhoneParam;
import com.witmore.neutron.ai.web.controller.vo.UserSession;
import com.witmore.neutron.ai.web.filter.GlobalAccountSession;
import com.witmore.neutron.ai.web.service.SmsService;
import com.witmore.neutron.ai.web.service.UserBindResult;
import com.witmore.neutron.ai.web.service.UserService;
import com.witmore.neutron.ai.web.service.impl.SmsServiceImpl;
import com.witmore.neutron.ai.web.wechat.dto.WechatUserInfo;
import com.witmore.neutron.ai.web.wechat.service.WechatOAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

/**
 * V2 用户相关接口
 * Author: 豆子高
 * Date: 2025/1/12 00:00
 */
@Slf4j
@RestController
@RequestMapping("/v2/user")
public class UserControllerV2 {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private WechatOAuthService wechatOAuthService;

    @Autowired
    private SmsService smsService;

    @Value("${witmore.session.bind-phone-times:50}")
    private Integer bindPhoneTimes;


    /**
     * 获取当前用户详情（从数据库获取最新信息）
     */
    @GetMapping("/info")
    @ResponseBody
    public ResponseResult<UserSession> getUserInfo() {
        // 获取当前登录用户会话（仅用于获取用户ID）
        UserSession currentUser = GlobalAccountSession.getUserInfo();
        if (currentUser == null) {
            return ResponseResult.fail(401, "用户未登录");
        }
        // 可以根据需要添加其他字段
        return ResponseResult.success(userService.setUserSession(currentUser.getId()));
    }

    /**
     * 发送验证码（通用接口，需要登录）
     * 当前支持场景：绑定手机号
     */
    @PostMapping("/sendSmsCode")
    @ResponseBody
    public ResponseResult<Void> sendSmsCode(@RequestBody SendSmsCodeParam param) {
        // 获取当前登录用户信息
        UserSession currentUser = GlobalAccountSession.getUserInfo();
        if (currentUser == null) {
            return ResponseResult.fail(401, "用户未登录");
        }

        // 参数校验
        if (param == null || !StringUtils.hasText(param.getPhone())) {
            return ResponseResult.fail(400, "手机号不能为空");
        }

        if (!StringUtils.hasText(param.getScene())) {
            return ResponseResult.fail(400, "场景类型不能为空");
        }

        // 验证手机号格式
        if (!isValidPhone(param.getPhone())) {
            return ResponseResult.fail(400, "手机号格式不正确");
        }

        // 根据场景进行不同的业务校验
        ResponseResult<Void> validationResult = validateSceneBusinessRules(param, currentUser);
        if (validationResult.getCode() != 200) {
            return validationResult;
        }

        // 发送验证码
        boolean success = smsService.sendVerificationCode(param.getPhone(), param.getScene());
        if (success) {
            return ResponseResult.success();
        } else {
            return ResponseResult.fail(500, "验证码发送失败，请稍后重试");
        }
    }

    /**
     * 根据场景验证业务规则
     */
    private ResponseResult<Void> validateSceneBusinessRules(SendSmsCodeParam param, UserSession currentUser) {
        if (SmsServiceImpl.SCENE_BIND_PHONE.equals(param.getScene())) {
            // 绑定手机号场景：检查手机号是否已被其他用户绑定
            UserDO existingUser = userMapper.selectOne(new LambdaQueryWrapper<UserDO>()
                    .eq(UserDO::getUserPhone, param.getPhone())
                    .ne(UserDO::getId, currentUser.getId()));
            if (existingUser != null) {
                return ResponseResult.fail(400, "该手机号已被其他用户绑定");
            }
        } else {
            return ResponseResult.fail(400, "不支持的场景类型");
        }

        return ResponseResult.success();
    }

    /**
     * 当前用户绑定手机号
     */
    @PostMapping("/bindPhone")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> bindPhone(@RequestBody UserBindPhoneParam param) {
        // 获取当前登录用户信息
        UserSession currentUser = GlobalAccountSession.getUserInfo();
        if (currentUser == null) {
            return ResponseResult.fail(401, "用户未登录");
        }

        // 参数校验
        if (param == null || !StringUtils.hasText(param.getPhone())) {
            return ResponseResult.fail(400, "手机号不能为空");
        }

        if (!StringUtils.hasText(param.getCode())) {
            return ResponseResult.fail(400, "验证码不能为空");
        }

        // 验证手机号格式
        if (!isValidPhone(param.getPhone())) {
            return ResponseResult.fail(400, "手机号格式不正确");
        }

        // 验证短信验证码（绑定手机号场景）
        boolean codeValid = smsService.verifyCode(param.getPhone(), param.getCode(), SmsServiceImpl.SCENE_BIND_PHONE);
        if (!codeValid) {
            return ResponseResult.fail(500, "验证码错误或已过期");
        }

        // 检查手机号是否已被其他用户绑定
        UserDO existingUser = userMapper.selectOne(new LambdaQueryWrapper<UserDO>()
                .eq(UserDO::getUserPhone, param.getPhone())
                .ne(UserDO::getId, currentUser.getId()));

        if (existingUser != null) {
            return ResponseResult.fail(400, "该手机号已被其他用户绑定");
        }

        // 更新当前用户的手机号
        UserDO userDO = userMapper.selectById(currentUser.getId());
        if (userDO == null) {
            return ResponseResult.fail(404, "用户不存在");
        }

        // 检查用户是否已经绑定过手机号（避免重复奖励）
        boolean isFirstBindPhone = !StringUtils.hasText(userDO.getUserPhone());

        // 记录绑定前的剩余次数
        Integer beforeRemainingTimes = userDO.getSessionRemainingTimes() != null ?
            userDO.getSessionRemainingTimes() : 0;

        userDO.setUserPhone(param.getPhone());
        userDO.setUpdateTime(LocalDateTime.now());

        // 如果是首次绑定手机号，增加奖励次数
        if (isFirstBindPhone) {
            Integer afterRemainingTimes = beforeRemainingTimes + bindPhoneTimes;
            userDO.setSessionRemainingTimes(afterRemainingTimes);
        }

        int result = userMapper.updateById(userDO);
        if (result > 0) {
            // 如果是首次绑定手机号，创建充值记录
            if (isFirstBindPhone) {
                userService.createRechargeRecord(userDO, bindPhoneTimes, "绑定手机号奖励", currentUser.getId(), currentUser.getUserName(),
                    beforeRemainingTimes, beforeRemainingTimes + bindPhoneTimes);
            }
            // 更新当前会话中的用户信息
            currentUser.setUserPhone(param.getPhone());
            GlobalAccountSession.setUserInfo(currentUser);
            return ResponseResult.success("手机号绑定成功");
        } else {
            return ResponseResult.fail(500, "手机号绑定失败");
        }
    }

    /**
     * 当前用户绑定微信openid 网页授权code
     */
    @PostMapping("/bindOpenid/code")
    @ResponseBody
    public ResponseResult<String> bindOpenid(@RequestBody UserBindOpenidParam param) {
        // 获取当前登录用户信息
        UserSession currentUser = GlobalAccountSession.getUserInfo();
        if (currentUser == null) {
            return ResponseResult.fail(401, "用户未登录");
        }

        // 1. 校验当前用户中的用户手机号信息是否存在
        if (!StringUtils.hasText(currentUser.getUserPhone())) {
            return ResponseResult.fail(400, "当前用户登录信息异常，未获取到手机号信息");
        }

        // 参数校验
        if (param == null || !StringUtils.hasText(param.getCode())) {
            return ResponseResult.fail(400, "微信授权码不能为空");
        }

        try {
            // 2. 根据code获取微信access_token（带缓存和自动刷新机制）
            WechatAuthAccessToken accessToken = wechatOAuthService.getValidAccessToken(param.getCode(), null);
            if (accessToken == null || !StringUtils.hasText(accessToken.getOpenid())) {
                return ResponseResult.fail(400, "获取微信access_token失败");
            }

            String newOpenid = accessToken.getOpenid();

            // 获取当前用户的完整信息
            UserDO currentUserDO = userMapper.selectById(currentUser.getId());
            if (currentUserDO == null) {
                return ResponseResult.fail(404, "用户不存在");
            }

            // 尝试获取微信用户详细信息（包括昵称和头像）
            WechatUserInfo wechatUserInfo = null;
            try {
                if ("snsapi_userinfo".equals(accessToken.getScope())) {
                    // 直接使用已获取的有效token
                    wechatUserInfo = wechatOAuthService.getUserInfo(
                            accessToken.getAccessToken(), accessToken.getOpenid());
                }
            } catch (Exception e) {
                log.warn("获取微信用户详细信息失败，但不影响绑定操作: {}", e.getMessage());
            }

            // 使用UserService的新重载方法，支持同时更新昵称和头像
            UserBindResult bindResult;
            if (wechatUserInfo == null) {
                wechatUserInfo = new WechatUserInfo();
                wechatUserInfo.setOpenid(accessToken.getOpenid());
            }
            bindResult = userService.bindUserOpenid(currentUserDO, wechatUserInfo);
            if (bindResult.isSuccess()) {
                // 更新当前会话中的用户信息
                UserDO updatedUser = bindResult.getUpdatedUser();
                if (updatedUser != null) {
                    currentUser.setWxOpenid(updatedUser.getWxOpenid());
                    if (StringUtils.hasText(updatedUser.getUserName())) {
                        currentUser.setUserName(updatedUser.getUserName());
                    }
                    if (StringUtils.hasText(updatedUser.getAvatarUrl())) {
                        currentUser.setAvatarUrl(updatedUser.getAvatarUrl());
                    }
                } else {
                    // 如果没有返回更新的用户对象，至少更新openid
                    currentUser.setWxOpenid(newOpenid);
                }
                GlobalAccountSession.setUserInfo(currentUser);
                return ResponseResult.success(bindResult.getMessage());
            } else {
                return ResponseResult.fail(400, bindResult.getMessage());
            }

        } catch (Exception e) {
            return ResponseResult.fail(500, "获取微信openid失败: " + e.getMessage());
        }
    }

    /**
     * 验证手机号格式
     */
    private boolean isValidPhone(String phone) {
        if (!StringUtils.hasText(phone)) {
            return false;
        }
        // 简单的手机号验证，11位数字，以1开头
        return phone.matches("^1[3-9]\\d{9}$");
    }
}
